package com.jhhc.StormSurgeForecast.StormSurge.ServiceImpl;

import com.jhhc.StormSurgeForecast.AstronomicalTide.Dao.BDMS_CALCULATESCHEME_M1Mapper;
import com.jhhc.StormSurgeForecast.AstronomicalTide.Dao.BDMS_FBC_RESULT_AMapper;
import com.jhhc.StormSurgeForecast.AstronomicalTide.Pojo.BDMS_CALCULATESCHEME_M1;
import com.jhhc.StormSurgeForecast.AstronomicalTide.Service.BDMS_CALCULATESCHEME_MService;
import com.jhhc.StormSurgeForecast.AstronomicalTide.Util.ReadUtil;
import com.jhhc.StormSurgeForecast.AstronomicalTide.Util.TimeUtil;
import com.jhhc.StormSurgeForecast.Calculate.util.DownloadUtil;
import com.jhhc.StormSurgeForecast.Calculate.util.ModelUtil;
import com.jhhc.StormSurgeForecast.StormSurge.Dao.BDMS_FBC_RESULT_A1Mapper;
import com.jhhc.StormSurgeForecast.StormSurge.Pojo.FBC.BDMS_FBC_OCEANMODEL_B;
import com.jhhc.StormSurgeForecast.StormSurge.Pojo.FBC.BDMS_FBC_RESULT_A;
import com.jhhc.StormSurgeForecast.StormSurge.Pojo.GZABO.*;
import com.jhhc.StormSurgeForecast.StormSurge.Service.BDMS_FBC_RESULT_AService;
import com.jhhc.StormSurgeForecast.StormSurge.Uitl.BinaryUtil;
import com.jhhc.StormSurgeForecast.StormSurge.Uitl.ColourUtil;
import com.jhhc.StormSurgeForecast.StormSurge.Uitl.JudgeUtil;
import com.jhhc.StormSurgeForecast.StormSurge.Uitl.VariableUtil;
import com.jhhc.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.el.ELClass;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service("BDMS_FBC_RESULT_AService")
@Transactional
public class BDMS_FBC_RESULT_AServiceImpl  implements BDMS_FBC_RESULT_AService {

    @Resource
    private BDMS_FBC_RESULT_AMapper bdms_fbc_result_aMapper;

    @Resource
    private BDMS_FBC_RESULT_A1Mapper bdmsFbcResultA1Mapper;

    @Resource
    private BDMS_CALCULATESCHEME_M1Mapper bdms_calculatescheme_m1Mapper;

    @Autowired
    private RedisUtil redisTemplate;

    @Override
    public List<BDMS_FBC_RESULT_A> getCalResultsByGrid(String CalSchemeId,String AreaName,
                                                       String StartTime, String EndTime, Integer Dttp, Integer GridId) {
        return bdmsFbcResultA1Mapper.getCalResultsByGrid(CalSchemeId,AreaName, StartTime, EndTime, Dttp, GridId);
    }


    @Override
    public Result GetCalResultsByDomain(String calSchemeId, String startTime,String endTime,
                                        Integer dttp,boolean isData){
        Result result = new Result();
        List<BDMS_FBC_RESULT_A> aList = bdmsFbcResultA1Mapper.
                GetCalResultsByDomain(calSchemeId, startTime,endTime,dttp);
        if (aList != null && aList.size() > 0) {
            List<CalculationResults> calculationResultsList = new ArrayList<>();
            double maxs = 0.0;
            double mins = 0.0;
            for (int i = 0; i < aList.size(); i++) {
                if (aList.get(i).getDtvalues() != null && !"".equals(aList.get(i).getDtvalues())) {
                    CalculationResults calculationResult = new CalculationResults();
                    String[] values = aList.get(i).getDtvalues().split(",");
                    //double[] ints = Arrays.stream(values).mapToDouble(Integer::parseInt).toArray();
                    //List<String> doubles = Arrays.asList(values);
                    if (isData) {
                        int[] ints = Arrays.stream(values).mapToInt(Integer::parseInt).toArray();
                        calculationResult.setZ(ints);
                    }else {
                        calculationResult.setZColour(ColourUtil.
                                colourClassification(dttp,values,result.getColourInfo()));
                    }
                    calculationResult.setTime(aList.get(i).getDttm());
                    calculationResultsList.add(calculationResult);
                }
            }
            result.setMultiple(JudgeUtil.isMultiple(dttp));
            result.setCalculationResults(calculationResultsList);
            List<ColourInfo> colourInfos = new ArrayList<>();
            String[] colours = new String[]{"255,0,0","255,85,0","255,170,0","255,255,0","170,255,0",
                    "85,255,0","0,255,0","0,226,55","0,196,110","0,166,166","0,111,195","0,56,225","0,0,255",
                    "42,0,213","255,255,255"};
            double min = -3.77;
            double max = 3.82;
            double grid = (max - min) / 15;
            double scope = 3.82 - grid;
            double scope1 = 0.0;
            for (int i = 0; i < 15; i++) {
                ColourInfo colourInfo = new ColourInfo();
                colourInfo.setSort(i + 1);
                colourInfo.setColourRGB(colours[i]);
                if (i == 0) {
                    colourInfo.setScope(String.valueOf(scope));
                    scope1 = scope;
                }else if (i == 14) {
                    colourInfo.setScope(String.format("%.2f",-3.77 + grid));
                }else {
                    scope = scope - grid;
                    colourInfo.setScope(String.format("%.2f",scope1) + "," + String.format("%.2f",scope));
                    scope1 = scope;
                }
                colourInfos.add(colourInfo);
            }
            result.setColourInfo(colourInfos);
            return result;
        }else {
            return null;
        }
    }

    @Override
    public List<int[]> GetCalResultsByDomain1(String calSchemeId, String startTime, String endTime,
                                              Integer dttp) {
        List<BDMS_FBC_RESULT_A> aList = bdms_fbc_result_aMapper.
                GetCalResultsByDomain(calSchemeId, startTime,endTime,dttp);
        List<int[]> floatList = new ArrayList<>();
        for (BDMS_FBC_RESULT_A bdmsFbcResultA : aList) {
            if (bdmsFbcResultA.getDtvalues() != null && !"".equals(bdmsFbcResultA.getDtvalues())) {
                String[] values = bdmsFbcResultA.getDtvalues().split(",");
                int[] array = Arrays.stream(values).mapToInt(Integer::parseInt).toArray();
                floatList.add(array);
            }
        }
        return floatList;
    }


    @Override
    public int batchInsert(String path,String time,String calSchemeId,String areaName){
        List<String> urls = BinaryUtil.getConditions(path);
        List<BDMS_FBC_RESULT_A> aList = new ArrayList<>();
        BDMS_FBC_RESULT_A r;
        DecimalFormat a = new DecimalFormat("#,##0.00");
        DecimalFormat a1 = new DecimalFormat("#000");
        DecimalFormat a2 = new DecimalFormat("0000");
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar cal = Calendar.getInstance();
        try {
            cal.setTime(format.parse(time));
            for (int i = 0; i < urls.size(); i++) {
                System.out.println(urls.get(i));
                r = new BDMS_FBC_RESULT_A();
                r.setCschemeid(calSchemeId);
                r.setAreaname(areaName);
                r.setDtid(i);
                String tm = format.format(cal.getTime());
                r.setDttm(tm);
                cal.add(Calendar.HOUR,1);
                r.setDttp(0);
                BufferedReader br = new BufferedReader(new FileReader(urls.get(i)));
                String s = null;
                StringBuilder spots = new StringBuilder();
                while((s = br.readLine())!=null){//使用readLine方法，一次读一行
                    if (!"".equals(s)) {
                        StringBuilder resilt = new StringBuilder();
                        String[] data = s.split(",");
                        String dataz = data[2].trim();
                        BigDecimal db = new BigDecimal(dataz);
                        String z = db.toPlainString();
                        if (!"-99.900000".equals(z)) {
                            double d = Double.parseDouble(z);
                            String value = a.format(d);
                            double dbFormat = Double.parseDouble(value);
                            double dbs = dbFormat * 100;
                            double d1 = Math.round(dbs);
                            String values = "";
                            if (d1 > 0) {
                                values = a2.format(d1);
                            }if (d1 < 0){
                                values = a1.format(d1);
                            }
                            if (d1 == 0) {
                                d1 = 0 - d1;
                                values = a2.format(d1);
                            }
                            resilt.append(values).append(",");
                            spots.append(resilt.toString());
                        }
                    }
                }
                r.setDtvalues(spots.toString());
                aList.add(r);
                br.close();
            }
        } catch (ParseException e) {
            e.printStackTrace();
            System.out.println("时间转换异常");
        } catch (IOException e){
            e.printStackTrace();
            System.out.println("文件读取异常");
        }

        int num = 0;//insert插入总数量
        int count = 0;//insert插入数量
        // 由于数据库对于插入字段的限制，在这里对批量插入的数据进行分批处理
        int batchCount = 400;//每批commit的个数
        int batchLastIndex = batchCount - 1;// 每批最后一个的下标
        for (int index = 0; index < aList.size() -1;) {
            if(batchLastIndex > aList.size() - 1){
                batchLastIndex = aList.size() - 1;
                count = bdmsFbcResultA1Mapper.batchInsert(aList.subList(index,batchLastIndex + 1));
                num+=count;
                break;
            }else {
                count = bdmsFbcResultA1Mapper.batchInsert(aList.subList(index,batchLastIndex + 1));
                index = batchLastIndex + 1;
                batchLastIndex = index + (batchCount - 1);
            }
            num+=count;
        }
        return num;
    }

    @Async(value = "asyncServiceExecutor")
    @Override
    public void insertByDomain(List<String> filePaths, String url, String token, String localPath,
                               String calSchemeId, String areaName, BDMS_FBC_OCEANMODEL_B bdmsFbcOceanmodelB,
                               BDMS_CALCULATESCHEME_M1 bdmsCalculateschemeM1) {
        try {
            TimeUtil timeUtil = new TimeUtil();
            DownloadUtil downloadUtil = new DownloadUtil();
            //下载文件
            downloadUtil.downloadBtfup(url,token,filePaths,localPath);
            //读取文件入库
            List<BDMS_FBC_RESULT_A> aList = ReadUtil.readBtfup(localPath,calSchemeId,
                    timeUtil.dateAddHour(bdmsCalculateschemeM1.getDtmforecast(),bdmsFbcOceanmodelB.getOutstartindexArea()),
                    areaName, ModelUtil.modelType(bdmsFbcOceanmodelB.getModelid()));
            // 由于数据库对于插入字段的限制，在这里对批量插入的数据进行分批处理
            int batchCount = 400;//每批commit的个数
            int batchLastIndex = batchCount - 1;// 每批最后一个的下标
            for (int index = 0; index < aList.size() -1;) {
                if(batchLastIndex > aList.size() - 1){
                    batchLastIndex = aList.size() - 1;
                    bdmsFbcResultA1Mapper.batchInsert(aList.subList(index,batchLastIndex + 1));
                    break;
                }else {
                    bdmsFbcResultA1Mapper.batchInsert(aList.subList(index,batchLastIndex + 1));
                    index = batchLastIndex + 1;
                    batchLastIndex = index + (batchCount - 1);
                }
            }
            bdms_calculatescheme_m1Mapper.updateArea("2",calSchemeId);
        } catch (ParseException | IOException e) {
            e.printStackTrace();
            bdms_calculatescheme_m1Mapper.updateArea("3",calSchemeId);
        }
    }

    /**
     *
     * @param path 路径
     * @param time 时间
     * @param calSchemeId 计算方案id
     * @param areaName 区域名称
     */
    @Async(value = "asyncServiceExecutor")
    @Override
    public void insertCalResultByCSDomain(String path, String time, String calSchemeId,
                                         String areaName,String modelId) {
        try {
            List<BDMS_FBC_RESULT_A> aList = ReadUtil.readFors63(path,calSchemeId,areaName,time,modelId);
            if (aList != null && aList.size() > 0) {
                // 由于数据库对于插入字段的限制，在这里对批量插入的数据进行分批处理
                int batchCount = 10;//每批commit的个数
                int batchLastIndex = batchCount - 1;// 每批最后一个的下标
                for (int index = 0; index < aList.size() -1;) {
                    if(batchLastIndex > aList.size() - 1){
                        batchLastIndex = aList.size() - 1;
                        bdms_fbc_result_aMapper.batchInsert(aList.subList(index,batchLastIndex + 1));
                        break;
                    }else {
                        bdms_fbc_result_aMapper.batchInsert(aList.subList(index,batchLastIndex + 1));
                        index = batchLastIndex + 1;
                        batchLastIndex = index + (batchCount - 1);
                    }
                }
                bdms_calculatescheme_m1Mapper.updateArea("2",calSchemeId);
            }
        } catch (ParseException | IOException e) {
            e.printStackTrace();
            bdms_calculatescheme_m1Mapper.updateArea("3",calSchemeId);
        }
//        if (path.contains("64")) {
//            aList = ReadUtil.readFors64(path,calSchemeId,areaName,time, modelId);
//        }else {
//            aList = ReadUtil.readFors63(path,calSchemeId,areaName,time, modelId);
//        }
    }

    @Override
    public List<BDMS_FBC_RESULT_A> getGridDataBySeaWall(String CSCHEMEID,String Grid, String StartTime, String EndTime, Integer DTTP) {
        return bdms_fbc_result_aMapper.getGridDataBySeaWall(CSCHEMEID, Grid, StartTime, EndTime, DTTP);
    }
    @Override
    public ResultData GetDateByGrid(String type,String calSchemeId,String startTime, String endTime,
                                    String grid, boolean rule,String typeofpier,Integer number,String dtNm) {
        List<BDMS_FBC_RESULT_A> aList1 =
                bdms_fbc_result_aMapper.GetDateByGrid(calSchemeId, startTime, endTime, grid);
        List<BDMS_FBC_RESULT_A> aList2 =
                bdms_fbc_result_aMapper.GetDateByGrid2(calSchemeId, startTime, endTime, grid);
        BinaryUtil binaryUtil = new BinaryUtil();
        return binaryUtil.GZAclassification(type, aList1, aList2,
                rule, typeofpier,number,dtNm);
    }

    @Override
    public List<BDMS_FBC_RESULT_A> queryByCschemeId(String cschemeId) {
        return bdmsFbcResultA1Mapper.queryByCschemeId(cschemeId);
    }

    @Override
    public int deleteByCschemeId(String cschemeId) {
        return bdms_fbc_result_aMapper.deleteByCschemeId(cschemeId);
    }

}
